package com.sample.Tetris;

import java.util.ArrayList;
import java.util.Random;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Rect;
import android.os.Handler;
import android.os.Message;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.*;
import android.graphics.Color;
import android.view.KeyEvent;

public class TetrisView extends View implements OnTouchListener{
	private Random ran = new Random();
	private Shape shape1;
	private Paint paint1 = new Paint();
	private int[][] TileGrid = new int[10][20];
	private Rect[][] rect = new Rect[10][20];
	private boolean blocked = false;
	private boolean sideBlocked = false;
	private boolean moveBlocked = false;
	private boolean lose = false;
	private boolean hasMoved = false;
	private boolean hasTurned = false;
	long LastMove;
	int delay = 1000;

	public TetrisView(Context context) {
		super(context);
		setFocusable(true);
		setFocusableInTouchMode(true);
		for (int x = 0; x < 10; x++) {
			for (int y = 0; y < 20; y++) {
				rect[x][y] = new Rect(x * 48, y * 36, (x + 1) * 48,
						(y + 1) * 36);
			}
		}
	}

	public TetrisView(Context context, AttributeSet attrs) {
		super(context, attrs);
		setFocusable(true);
		setFocusableInTouchMode(true);
		for (int x = 0; x < 10; x++) {
			for (int y = 0; y < 20; y++) {
				rect[x][y] = new Rect(x * 48, y * 36, (x + 1) * 48,
						(y + 1) * 36);
			}
		}
	}
	public void onDraw(Canvas c) {
		update();
		paint1.setColor(Color.BLUE);
		for (int x = 0; x < 10; x++) {
			for (int y = 0; y < 20; y++) {
				if (TileGrid[x][y] != 0) {
					paint1.setColor(TileGrid[x][y]);
					c.drawRect(rect[x][y], paint1);
					// fix shape blinking
				}
			}
		}
	}


	private void checkRow() {
		int count = 0;
		for (int w = 0; w < 20; w++) {
			for (int v = 0; v < 10; v++) {
				if (TileGrid[v][19] != 0) {
					count++;
				}
				if (count == 10) {
					int[][] newTileGrid = new int[10][20];
					// fix
					for (int x = 0; x < 10; x++) {
						for (int y = 0; y < 19; y++) {
							newTileGrid[x][y + 1] = TileGrid[x][y];
						}
					}
					TileGrid = newTileGrid;
				}
			}
			count = 0;
		}
	}

	public boolean onKeyDown(int keyCode, KeyEvent msg) {
		int[] tempCoords = shape1.getCoords();
		int[][] newTileGrid = TileGrid;
		if (keyCode == KeyEvent.KEYCODE_DPAD_LEFT && hasMoved == false) {
			tempCoords = shape1.getCoords();
			newTileGrid = TileGrid;
			for (int x = 0; x < shape1.getCoords().length; x += 2) {
				for (int w = 0; w < 10; w++) {
					for (int y = 0; y < 19; y++) {
						if (tempCoords[x] == w && tempCoords[x + 1] == y) {
							newTileGrid[w][y] = 0;
						}
					}
				}
				if (tempCoords[x] - 1 == -1) {
					sideBlocked = true;
				} else if (newTileGrid[tempCoords[x] - 1][tempCoords[x + 1]] != 0) {
					sideBlocked = true;
				}
			}
			if (sideBlocked == false) {
				hasMoved = true;
				for (int x = 0; x < shape1.getCoords().length; x += 2) {
					TileGrid[shape1.getCoord(x)][shape1.getCoord(x + 1)] = 0;
					shape1.setCoords(x, shape1.getCoord(x) - 1);
				}
			}
		}
		if (keyCode == KeyEvent.KEYCODE_DPAD_RIGHT && hasMoved == false) {
			tempCoords = shape1.getCoords();
			newTileGrid = TileGrid;
			for (int x = 0; x < shape1.getCoords().length; x += 2) {
				for (int w = 0; w < 10; w++) {
					for (int y = 0; y < 19; y++) {
						if (tempCoords[x] == w && tempCoords[x + 1] == y) {
							newTileGrid[w][y] = 0;
						}
					}
				}
				if (tempCoords[x] + 1 == 10) {
					sideBlocked = true;
				} else if (newTileGrid[tempCoords[x] + 1][tempCoords[x + 1]] != 0) {
					sideBlocked = true;
				}
			}
			if (sideBlocked == false) {
				hasMoved = true;
				for (int x = 0; x < shape1.getCoords().length; x += 2) {
					TileGrid[shape1.getCoord(x)][shape1.getCoord(x + 1)] = 0;
					shape1.setCoords(x, shape1.getCoord(x) + 1);
				}
			}
		}
		// add collision
		if (keyCode == KeyEvent.KEYCODE_DPAD_UP && hasTurned == false) {
			newTileGrid = TileGrid;
			for (int x = 0; x < shape1.getCoords().length; x += 2) {
				for (int w = 0; w < 10; w++) {
					for (int y = 0; y < 19; y++) {
						if (tempCoords[x] == w && tempCoords[x + 1] == y) {
							newTileGrid[w][y] = 0;
						}
					}
				}
				tempCoords = shape1.turn(1);
				for (int v = 0; v < tempCoords.length; v += 2) {
					if (tempCoords[v] < 0 || tempCoords[v] > 9
							|| tempCoords[v + 1] < 0 || tempCoords[v + 1] > 19) {
						moveBlocked = true;
					} else if (newTileGrid[tempCoords[v]][tempCoords[v + 1]] != 0) {
						moveBlocked = true;
					}
				}
				if (moveBlocked == false) {
					for (int i = 0; i < shape1.getCoords().length; i += 2) {
						TileGrid[shape1.getCoord(i)][shape1.getCoord(i + 1)] = 0;
					}
					tempCoords = shape1.turn(-1);
					shape1.setCoords(shape1.turn(1));
					hasTurned = true;
				}
			}
		}
		if (keyCode == KeyEvent.KEYCODE_DPAD_DOWN && hasTurned == false) {
			newTileGrid = TileGrid;
			for (int x = 0; x < shape1.getCoords().length; x += 2) {
				newTileGrid[shape1.getCoord(x)][shape1.getCoord(x + 1)] = 0;
			}
			tempCoords = shape1.turn(-1);
			for (int x = 0; x < tempCoords.length; x += 2) {
				if (tempCoords[x] < 0 || tempCoords[x] > 9
						|| tempCoords[x + 1] < 0 || tempCoords[x + 1] > 19) {
					Log.d("debug", "block1");
					moveBlocked = true;
				} else if (newTileGrid[tempCoords[x]][tempCoords[x + 1]] != 0) {
					Log.d("debug", "block2");
					moveBlocked = true;
				}
			}
			if (moveBlocked == false) {
				for (int x = 0; x < shape1.getCoords().length; x += 2) {
					TileGrid[shape1.getCoord(x)][shape1.getCoord(x + 1)] = 0;
				}
				tempCoords = shape1.turn(1);
				shape1.setCoords(shape1.turn(-1));
				hasTurned = true;
			}
		}
		if (keyCode == KeyEvent.KEYCODE_SPACE) {
			// fix collision w/ squares, j, l, i
			tempCoords = shape1.getCoords();
			newTileGrid = TileGrid;
			for (int x = 0; x < shape1.getCoords().length; x += 2) {
				for (int w = 0; w < 10; w++) {
					for (int y = 0; y < 19; y++) {
						if (tempCoords[x] == w && tempCoords[x + 1] == y) {
							newTileGrid[w][y] = 0;
						}
					}
				}
			}
			int fin = 19;
			for (int x = 0; x < shape1.getCoords().length; x += 2) {
				for (int y = 0; y < 20; y++) {
					if (newTileGrid[tempCoords[x]][y] != 0) {
						int temp = y;
						if (temp < fin) {
							fin = temp - 1;
						}
					}
				}
			}
			int bot = 0;
			int increment;
			for (int x = 0; x < shape1.getCoords().length; x += 2) {
				if (bot < shape1.getCoord(x + 1)) {
					bot = shape1.getCoord(x + 1);
				}
			}
			for (int x = 0; x < shape1.getCoords().length; x += 2) {
				increment = bot - shape1.getCoord(x + 1);
				TileGrid[shape1.getCoord(x)][shape1.getCoord(x + 1)] = 0;
				shape1.setCoords(x + 1, fin - increment);
			}
		}
		if (keyCode == KeyEvent.KEYCODE_ENTER) {
			int error = 2 / 0;
		}
		sideBlocked = false;
		moveBlocked = false;
		return true;
	}
	public boolean onTouch(View v, MotionEvent event) {
		return true;
	}
	
	
	
	
	
	
	
	
	
	
	
	
	
	
	
	
	
	
	
	
	
	
	
	
	
	
	
	
	
	
	public void update() {
		long now = System.currentTimeMillis();

		if (now - LastMove > delay && lose == false) {
			if (shape1 == null) {
				addShape();
			}
			int[] tempCoords = shape1.getCoords();
			int[][] newTileGrid = TileGrid;
			hasMoved = false;
			hasTurned = false;
			if (blocked == false) {
				for (int x = 0; x < shape1.getCoords().length; x += 2) {
					for (int w = 0; w < 10; w++) {
						for (int y = 0; y < 19; y++) {
							if (tempCoords[x] == w && tempCoords[x + 1] == y) {
								newTileGrid[w][y] = 0;
							}
						}
					}
				}
				for (int x = 0; x < shape1.getCoords().length; x += 2) {
					if (shape1.getCoord(x + 1) >= 19) {
						blocked = true;
					} else if (newTileGrid[tempCoords[x]][tempCoords[x + 1] + 1] != 0) {
						blocked = true;
					}
				}
				shapeToGrid();
			}
			if (blocked == true) {
				blocked = false;
				addShape();
			}
			for (int x = 0; x < shape1.getCoords().length; x += 2) {
				TileGrid[shape1.getCoord(x)][shape1.getCoord(x + 1)] = 0;
				shape1.setCoords(x + 1, shape1.getCoord(x + 1) + 1);
			}
			shapeToGrid();
			LastMove = now;
			TetrisHandler.sleep(delay);
		}
	}
	private void addShape() {
		checkRow();
		if (delay > 500) {
			delay *= .95;
		}
		int random = ran.nextInt(7);
		if (random == 0) {
			shape1 = new IShape();
		}
		if (random == 1) {
			shape1 = new JShape();
		}
		if (random == 2) {
			shape1 = new LShape();
		}
		if (random == 3) {
			shape1 = new OShape();
		}
		if (random == 4) {
			shape1 = new SShape();
		}
		if (random == 5) {
			shape1 = new TShape();
		}
		if (random == 6) {
			shape1 = new ZShape();
		}
		int[] tempCoords = shape1.getCoords();
		for (int x = 0, y = 1; x < shape1.getCoords().length; x += 2, y += 2) {
			if (TileGrid[tempCoords[x]][tempCoords[y]] != 0) {
				lose = true;
			}
		}
		// add Lose code here
	}
	private void shapeToGrid() {
		int[] tempCoords = shape1.getCoords();
		for (int x = 0, y = 1; x < shape1.getCoords().length; x += 2, y += 2) {
			setTile(shape1.getColor(), tempCoords[x], tempCoords[y]);
		}
	}
	private RefreshHandler TetrisHandler = new RefreshHandler();

	class RefreshHandler extends Handler {
		@Override
		public void handleMessage(Message msg) {
			TetrisView.this.update();
			TetrisView.this.invalidate();
		}

		public void sleep(long delayMillis) {
			this.removeMessages(0);
			sendMessageDelayed(obtainMessage(0), delayMillis);
		}
	};

	public void setTile(int color, int x, int y) {
		if (y >= 0 && x >= 0 && x < 10 && y < 20) {
			TileGrid[x][y] = color;
		}
	}

}
